package cn.mw.cmdb.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.mw.cmdb.controller.ModelController;
import cn.mw.cmdb.entity.FieldViewAuthType;
import cn.mw.cmdb.entity.ModelGroupInfo;
import cn.mw.cmdb.exception.WarnTitleException;
import cn.mw.cmdb.param.BatchEditorViewInstance;
import cn.mw.cmdb.param.PropertySearchParam;
import cn.mw.cmdb.param.TableSearchParam;
import cn.mw.cmdb.view.InstanceInpuFieldsView;
import cn.mw.components.mongodb.entity.CriteriaOpsType;
import cn.mw.components.mongodb.entity.SearchParam;
import cn.mw.components.mongodb.entity.SubCondition;
import cn.mw.components.mongodb.tool.MongoUtils;
import cn.mw.microMonitorCommon.api.cmdb.MwCMDBCommonApi;
import cn.mw.microMonitorCommon.api.cmdb.TableIdEnum;
import cn.mw.microMonitorCommon.api.common.ResponseBase;
import cn.mw.microMonitorCommon.entity.cmdb.*;
import cn.mw.microMonitorCommon.entity.common.FieldConditionDto;
import cn.mw.microMonitorCommon.param.MwModuleFieldParam;
import cn.mw.microMonitorCommon.param.QueryPropertyInfoParam;
import cn.mw.microMonitorCommon.util.SpringUtils;
import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static cn.mw.cmdb.controller.MwProcessCallCMDBController.propertyCatologTypeList;
import static cn.mw.cmdb.util.MwCMDBMongoDBApi.getSearchParamList;

@DubboService
@Slf4j
@Component
public class MwCMDBCommonApiImpl implements MwCMDBCommonApi {

    private CmdbServiceManage cmdbServiceManage;

    public MwCMDBCommonApiImpl(CmdbServiceManage cmdbServiceManage) {
        this.cmdbServiceManage = cmdbServiceManage;
    }

    @Override
    public MwProcessCallInstanceInfo getInstanceListAndHeader(MwModuleFieldParam mwModuleFieldParam) throws Exception {
        MwProcessCallInstanceInfo processCallInstanceInfo = new MwProcessCallInstanceInfo();
        TableSearchParam tableSearchParam = new TableSearchParam();
        //通用实例字段
        tableSearchParam.setTableId(TableIdEnum.commonInstance.getCode());
        TableHeaderAndDataManage dataManage = SpringUtils.getBean(TableHeaderAndDataManage.class);
        try {
            List<FieldConditionDto> conditionDtoList = mwModuleFieldParam.getConditionDtoList();
            tableSearchParam.setIgnoreDataAuth(mwModuleFieldParam.isIgnoreDataAuth());
            SearchParam searchParamList = getSearchParamList(conditionDtoList);
            BeanUtil.copyProperties(searchParamList, tableSearchParam, CopyOptions.create().setIgnoreNullValue(true));
            List<TableHeaderItem> tableHeaderItems = dataManage.listHeaders(tableSearchParam);
            List<Map> list = (List<Map>) dataManage.listTableData(tableSearchParam);
            processCallInstanceInfo.setInstanceList(list);
            processCallInstanceInfo.setHeaderItems(tableHeaderItems);
        } catch (Exception e) {
            throw new WarnTitleException("process-call-model-err");
        }
        return processCallInstanceInfo;
    }

    @Override
    public List<ModelGroupInfoView> searchModelGroupInfoByPath(String groupId) throws Exception {
        ModelGroupServiceImpl modelGroupService = (ModelGroupServiceImpl) cmdbServiceManage.getModelService(ModelGroupServiceImpl.ID);
        SearchParam searchParam = new SearchParam();
        searchParam.setOperation(CriteriaOpsType.and.name());
        List<String> values = new ArrayList<>();
        values.add(groupId);

        SearchParam subSearchParam = new SearchParam();
        subSearchParam.addSubCondition(MongoUtils.getFieldName(ModelGroupInfo::getPath)
                , new SubCondition(CriteriaOpsType.elemMatch.name(), values));
        searchParam.addSearchParam(subSearchParam);

        //只返回第2级分组
        subSearchParam = new SearchParam();
        subSearchParam.addSubCondition(MongoUtils.getFieldName(ModelGroupInfo::getPath)
                , new SubCondition(CriteriaOpsType.size.name(), 1));
        searchParam.addSearchParam(subSearchParam);

        List<ModelGroupInfo> modelGroupInfos = modelGroupService.selectList(searchParam);
        List<ModelGroupInfoView> ret = null;
        if (null != modelGroupInfos) {
            ret = new ArrayList<>();
            for (ModelGroupInfo modelGroupInfo : modelGroupInfos) {
                ModelGroupInfoView modelGroupInfoView = new ModelGroupInfoView();
                BeanUtil.copyProperties(modelGroupInfo, modelGroupInfoView);
                ret.add(modelGroupInfoView);
            }
        }
        return ret;
    }

    @Override
    public ModelGroupInfoView selectModelGroupId(String groupId) throws Exception {
        ModelGroupServiceImpl modelGroupService = (ModelGroupServiceImpl) cmdbServiceManage.getModelService(ModelGroupServiceImpl.ID);
        ModelGroupInfo param = new ModelGroupInfo();
        param.setId(groupId);
        ModelGroupInfo modelGroup = modelGroupService.selectById(param);
        if (null != modelGroup) {
            ModelGroupInfoView modelGroupInfoView = new ModelGroupInfoView();
            BeanUtil.copyProperties(modelGroup, modelGroupInfoView);
            return modelGroupInfoView;
        }
        return null;
    }

    @Override
    public MwImportResultParam getImportDataInfo(ModelExportDataInfoListParam param) throws Exception {
        InstanceViewImpl viewService = (InstanceViewImpl) cmdbServiceManage.getModelService(InstanceViewImpl.ID);
        MultipartFile file = new CustomMultipartFile("file", param.getOriginalFileName(), param.getContentType(), param.getFileBytes());
        MwImportResultParam importDataInfo = viewService.getImportDataInfo(file, param, null);
        return importDataInfo;
    }

    @Override
    public List getPropertyInfosByModelId(QueryPropertyInfoParam param) throws Exception {
        //从对应模型中获取属性类型分组数据
        ModelController bean = SpringUtils.getBean(ModelController.class);
        PropertySearchParam propertySearchParam = new PropertySearchParam();
        propertySearchParam.setModelId(param.getModelId());
        propertySearchParam.setInputType(Strings.isNullOrEmpty(param.getInputType()) ? FieldViewAuthType.sel.name() : param.getInputType());
        ResponseBase responseBase = bean.listInputProperty(propertySearchParam);
        List<InstanceInpuFieldsView> newList = new ArrayList<>();
        if (responseBase != null) {
            Object data = responseBase.getData();
            if (data instanceof List) {
                List<InstanceInpuFieldsView> dataList = (List<InstanceInpuFieldsView>) data;
                for (InstanceInpuFieldsView fieldsView : dataList) {
                    String type = fieldsView.getType();
                    if (!propertyCatologTypeList.contains(type)) {
                        newList.add(fieldsView);
                    }
                }
            }
        }
        return newList;
    }

    @Override
    public void batchUpdateInstanceInfo(Map<String, Object> map) throws Exception {
        InstanceServiceImpl instanceService = (InstanceServiceImpl) cmdbServiceManage.getModelService(InstanceServiceImpl.ID);
        // 按照状态进行批量更新
        BatchEditorViewInstance batchEditorViewInstance = JSON.parseObject(JSON.toJSONString(map), BatchEditorViewInstance.class);
        instanceService.batchUpdate(batchEditorViewInstance);
    }


}
